package com.ruoyi.web.controller.store.calc;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.StoreCalc;
import com.ruoyi.common.core.domain.entity.StoreCalcDetail;
import com.ruoyi.common.core.domain.entity.StoreIn;
import com.ruoyi.common.core.domain.entity.StoreInDetail;
import com.ruoyi.common.core.domain.entity.Vendor;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.TimeUtils;
import com.ruoyi.system.mapper.*;
import org.springframework.security.core.parameters.P;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author：liyouxin
 * @date：2023/11/13 12:07
 */
@RestController
@RequestMapping("/calc/vendor")
public class VendorCalcController extends BaseController {
    @Resource
    private StoreCalcMapper storeCalcMapper;

    @Resource
    private StoreCalcDetailMapper storeCalcDetailMapper;

    @Resource
    private VendorMapper vendorMapper;

    @Resource
    private StoreOutMapper storeOutMapper;

    @Resource
    private StoreInMapper storeInMapper;

    @Resource
    private StoreInDetailMapper storeInDetailMapper;

    @Log(title = "查询供应商盘点", businessType = BusinessType.OTHER)
    @GetMapping("/list")
    public TableDataInfo list(StoreCalc storeCalc)
    {
        startPage();
        List<StoreCalc> list = storeCalcMapper.selectList(storeCalc);
        return getDataTable(list);
    }

    @Log(title = "触发供应商盘点", businessType = BusinessType.OTHER)
    @GetMapping("/add")
    public AjaxResult add()
    {
        List<Vendor> vendors = vendorMapper.selectList(Vendor.builder().build());
        if (CollectionUtils.isEmpty(vendors)) {
            return success();
        }
        for (Vendor vendor : vendors) {
            handleCalc(vendor);
        }
        return success();
    }

    private Integer getTotalAmount(Long storeCalcId) {
        List<StoreCalcDetail> details = storeCalcDetailMapper.selectList(StoreCalcDetail.builder().calcId(storeCalcId).build());
        if (CollectionUtils.isEmpty(details)) {
            return 0;
        }
        return details.stream().map(StoreCalcDetail::getAmount).mapToInt(a -> a).sum();
    }

    private void handleCalc(Vendor vendor) {
        Long vendorId = vendor.getId();
        List<StoreIn> storeIns = storeInMapper.selectThisMonth(StoreIn.builder()
                .vendorId(vendorId).build());
        List<StoreInDetail> storeInDetails = new ArrayList<>();
        StoreCalc storeCalc = getThisMonth(vendorId);
        if (storeCalc == null) {
            StoreCalc storeCalcCreate = new StoreCalc();
            storeCalcCreate.setVendorId(vendorId);
            storeCalcCreate.setCalcRange(TimeUtils.getYearMonth());
            storeCalcCreate.setCalcTime(new Date());
            storeCalcCreate.setCreateBy(SecurityUtils.getNickName());
            storeCalcMapper.insert(storeCalcCreate);
            storeCalc = storeCalcCreate;
        }
        Long calcId = storeCalc.getId();
        if (CollectionUtils.isEmpty(storeIns)) {
            return;
        }

        for (StoreIn storeIn : storeIns) {
            storeInDetails.addAll(storeInDetailMapper.selectList(StoreInDetail.builder()
                    .inId(storeIn.getId()).build()));
        }
        Map<Long, Integer> storeAmountMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(storeInDetails)) {
            for (StoreInDetail detail : storeInDetails) {
                Long resourceId = detail.getResourceId();
                Integer amount = storeAmountMap.get(resourceId);
                if (amount == null) {
                    amount = 0;
                }
                amount = amount + Optional.ofNullable(detail.getAmount()).orElse(BigDecimal.ZERO).intValue();
                storeAmountMap.put(resourceId, amount);
            }
        }
        List<StoreCalcDetail> storeCalcDetails = storeCalcDetailMapper.selectList(StoreCalcDetail.builder().calcId(storeCalc.getId()).build());
        Map<Long, StoreCalcDetail> storeCalcDetailMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(storeCalcDetails)) {
            storeCalcDetailMap = storeCalcDetails.stream().collect(Collectors.toMap(StoreCalcDetail::getResourceId, s -> s));
        }
        // 先删除多余的
        for (Long resourceId : storeCalcDetailMap.keySet()) {
            if (storeAmountMap.get(resourceId) == null) {
                storeCalcDetailMapper.deleteById(storeCalcDetailMap.get(resourceId).getId());
            }
        }
        // 再创建没有的 或者 更新已有的
        for (Long resourceId : storeAmountMap.keySet()) {
            StoreCalcDetail storeCalcDetail = storeCalcDetailMap.get(resourceId);
            if (storeCalcDetail == null) {
                storeCalcDetail = new StoreCalcDetail();
                storeCalcDetail.setCalcId(calcId);
                storeCalcDetail.setAmount(storeAmountMap.get(resourceId));
                storeCalcDetail.setResourceId(resourceId);
                storeCalcDetail.setCreateBy(SecurityUtils.getNickName());
                storeCalcDetailMapper.insert(storeCalcDetail);
            } else {
                StoreCalcDetail storeCalcDetailUpdate = new StoreCalcDetail();
                storeCalcDetailUpdate.setId(storeCalcDetail.getId());
                storeCalcDetailUpdate.setAmount(storeAmountMap.get(resourceId));
                storeCalcDetailMapper.update(storeCalcDetailUpdate);
            }
        }
    }

    private StoreCalc getThisMonth(Long vendorId) {
        return storeCalcMapper.selectThisMonthOne(StoreCalc.builder().vendorId(vendorId).build());
    }
}
